
`include "common_header.verilog"

//  *************************************************************************
//  File : top_40g_contc
//  *************************************************************************
//  This program is controlled by a written license agreement.
//  Unauthorized reproduction or use is expressly prohibited.
//  Copyright (c) 2014 MorethanIP
//  Muenchner Strasse 199, 85757 Karlsfeld, Germany
//  info@morethanip.com
//  http://www.morethanip.com
//  *************************************************************************
//  Designed by : Daniel Koehler, Thomas Schrobenhauser
//  info@morethanip.com
//  *************************************************************************
//  Description : 40G MAC RX, TX datapath and Pause Control modules
//  Version     : $Id: top_40g_contc.v,v 1.15 2017/05/29 15:15:19 gc Exp $
//  *************************************************************************

module top_40g_contc (
   reset_rxclk,
   reset_txclk,
   xlgmii_txclk,
   xlgmii_txclk_ena,
   xlgmii_rxclk,
   rx_start,
   rx_end,
   rx_d,
   rx_dval,
   rx_final_size,
   frame_err,
   phy_err,
   rs_fault,
   rs_fault_ored,
   tx_val,
   tx_d,
   tx_final_size,
   tx_err,
   tx_end,
   tx_start,
   txipg_dval,
   txipg_eop,
   txipg_mod,
   txipg_crc,
   txipg_sub1,
   txipg_done,
   txipg_dic,
   txipg_norm,
   rx_data_int,
   rx_sop_int,
   rx_eop_int,
   rx_wren_int,
   rx_dval_int,
   rx_a_full,
   rx_stat_data,
   rx_stat_wren,
   rx_preamble,
   tx_stat_empty,
   tx_stat,
   tx_stat_pgen,
   tx_data_err_int,
   tx_data_int,
   tx_sop_int,
   tx_eop_int,
   tx_sav_int,
   tx_rden_int,
   tx_empty,
   tx_underflow,
   tx_rden_int_sop,
   tx_isidle,
   tx_preamble,
`ifdef MTIPM10_MAGIC_ENA
   magic_rxstop,
`endif
`ifdef MTIPMAC_1SIF
   os_tx_err,
`endif
   lowp_ena_t,
   pause_fwd,
   mac_addr,
   tx_enable,
   tx_pad_in,
   rx_enable,
   frm_lgth_max,
   sfd_any,
   tx_flush,
   pfc_mode,
`ifdef MTIPM64B_SHORT_IPG
   short_ipg,
`endif    
   rsv_stat_val,
   rsv_stat,
   rsv_stat_pfc,
   frm_align_err,
   tsv_stat_val,
   tsv_stat,
   tsv_stat_pfc,
   tsv_stat_pgen
   );

parameter       RX_STAT_DAT_WIDTH_64 = 25;

input   reset_rxclk;                    //  Active High reset for xlgmii_rxclk domain
input   reset_txclk;                    //  Active High reset for xlgmii_txclk domain
input   xlgmii_txclk;                   //  XLGMII Transmit Clock
input   xlgmii_txclk_ena;               //  XLGMII Transmit Clock Enable.
input   xlgmii_rxclk;                   //  XLGMII Receive Clock
input   rx_start;                       //  XLGMII Start of Frame
input   rx_end;                         //  XLGMII End of Frame
input   [63:0] rx_d;                    //  XLGMII Receive Data
input   rx_dval;                        //  XLGMII Receive Data valid
input   [2:0] rx_final_size;            //  XLGMII Frame Modulo - asserted with rx_end
input   frame_err;                      //  XLGMII Frame Error received
input   phy_err;                        //  XLGMII Error Control Code received
input   rs_fault;                       //  XLGMII Sequence Error (Local or Remote) received
input   rs_fault_ored;                  //  XLGMII Reconciliation LF or RF received
output  tx_val;                         //  XLGMII Transmit data valid
output  [63:0] tx_d;                    //  XLGMII Transmit data
output  [2:0] tx_final_size;            //  XLGMII Transmit final data word size
output  tx_err;                         //  XLGMII Transmit error
output  tx_end;                         //  XLGMII Transmit last word on tx_d (eop)
output  tx_start;                       //  XLGMII Transmit first word on tx_d (sop)
output  txipg_dval;                     //  Transmit enable (delayed)
output  [1:0] txipg_eop;                //  End of frame for Tx IPG calculation
output  [2:0] txipg_mod;                //  Last word modulo, valid when txipg_eop asserts
output  txipg_crc;                      //  MAC appends CRC
output  [1:0] txipg_sub1;               //  Idle block was removed, return to normal operation
input   txipg_done;                     //  Tx ipg done, next frame can be sent
input   [2:0] txipg_dic;                //  current DIC
input   [1:0] txipg_norm;               //  1:normal, 0:request to remove 1 block to compensate for MLD
output  [63:0] rx_data_int;             //  Receive Data to FIFO
output  rx_sop_int;                     //  Receive Start of Packet
output  rx_eop_int;                     //  Receive End of Packet
output  rx_wren_int;                    //  Receive Data FIFO write enable
output  rx_dval_int;                    //  Receive Data valid
input   rx_a_full;                      //  Receive Data FIFO almost full
output  [3 + RX_STAT_DAT_WIDTH_64-1:0] rx_stat_data;         //  Receive Frame Status & Error indications
output  rx_stat_wren;                   //  Receive Status FIFO write enable
output  [55:0] rx_preamble;             //  Receive frame preamble (stable from sop)
input   tx_stat_empty;                  //  Transmit Status FIFO Word Empty
input   [4:0] tx_stat;                  //  Transmit Status Word
input   tx_stat_pgen;                   //  Internally generated pause frame
input   tx_data_err_int;                //  Memory read error, need to corrupt frame
input   [63:0] tx_data_int;             //  Transmit Data from FIFO
input   tx_sop_int;                     //  Transmit Start of Packet
input   tx_eop_int;                     //  Transmit End of Packet
input   tx_sav_int;                     //  Transmit Data Section Available in FIFO
output  tx_rden_int;                    //  Transmit Data FIFO Read tx_enable
input   tx_empty;                       //  Transmit Data FIFO Empty
output  tx_underflow;                   //  Transmit Underflow
output  tx_rden_int_sop;                //  Transmit reads first word from FIFO
output  tx_isidle;                      //  Transmit Statemachine is in IDLE
input   [55:0] tx_preamble;             //  Transmit frame preamble (sampled at sop)
`ifdef MTIPM10_MAGIC_ENA
input   magic_rxstop;                   //  stop rx datapath writing into FIFO
`endif
`ifdef MTIPMAC_1SIF
output  os_tx_err;                      //  Transmit frame error
`endif
input   lowp_ena_t;                     //  Low Power Enable (sync'ed to txclk)
input   pause_fwd;                      //  Forward Pause Frames to Application
input   [47:0] mac_addr;                //  Device Ethernet MAC address
input   tx_enable;                      //  Enable / Disable MAC transmit path
input   tx_pad_in;                      //  Transmit Padding Enable
input   rx_enable;                      //  Enable / Disable MAC receive path
input   [15:0] frm_lgth_max;            //  Maximum Frame Length
input   sfd_any;                        //  Allow any SFD character
input   tx_flush;                       //  Flush egress pipeline
input   pfc_mode;                       //  PFC mode (1) or Link Pause mode (0)
`ifdef MTIPM64B_SHORT_IPG
input   short_ipg;                      //  if 1, short IPG used
`endif 
output  rsv_stat_val;                   //  Receive Statistics Vector valid
output  [31:0] rsv_stat;                //  Receive Statistics Vector
output  [7:0] rsv_stat_pfc;             //  pfc class bits from received PFC frame
output  frm_align_err;                  //  Frame Alignment Error Indication
output  tsv_stat_val;                   //  Transmit Statistic Vector Valid.
output  [24:0] tsv_stat;                //  Transmit Statistic Vector.
output  [7:0] tsv_stat_pfc;             //  the class enable of latest generated frame
output  tsv_stat_pgen;                  //  Internally generated pause frame

wire    tx_val;
wire    [63:0] tx_d;
wire    [2:0] tx_final_size;
wire    tx_err;
wire    tx_end;
wire    tx_start;
wire    txipg_dval;
wire    [1:0] txipg_eop;
wire    [2:0] txipg_mod;
wire    txipg_crc;
wire    [1:0] txipg_sub1;
wire    [63:0] rx_data_int;
wire    rx_sop_int;
wire    rx_eop_int;
wire    rx_wren_int;
wire    rx_dval_int;
wire    [3 + RX_STAT_DAT_WIDTH_64-1:0] rx_stat_data;
wire    rx_stat_wren;
wire    [55:0] rx_preamble;
wire    tx_rden_int;
wire    tx_underflow;
wire    tx_rden_int_sop;
wire    tx_isidle;
`ifdef MTIPMAC_1SIF
wire    os_tx_err;
`endif
wire    rsv_stat_val;
wire    [31:0] rsv_stat;
wire    [7:0] rsv_stat_pfc;
wire    frm_align_err;
wire    tsv_stat_val;
wire    [24:0] tsv_stat;
wire    [7:0] tsv_stat_pfc;
wire    tsv_stat_pgen;

//  sync'ed signals into rx clock domain
wire    pfc_mode_r;
wire    pfc_mode_t;
`ifdef MTIPM64B_SHORT_IPG
wire    short_ipg_t;
`endif

//  Sync async inputs
//  -----------------
mtip_xsync #(1) U_RSYNC (
          .data_in(pfc_mode),
          .reset(reset_rxclk),
          .clk(xlgmii_rxclk),
          .data_s(pfc_mode_r));

mtip_xsync #(1) U_TSYNC (
          .data_in(pfc_mode),
          .reset(reset_txclk),
          .clk(xlgmii_txclk),
          .data_s(pfc_mode_t));






`ifdef MTIPM64B_SHORT_IPG

mtip_xsync #(1) U_IPG_SYNC (
          .data_in(short_ipg),
          .reset(reset_txclk),
          .clk(xlgmii_txclk),
          .data_s(short_ipg_t));

`endif 


cont_40g_rxc 



#(
        // use instance parameters instead package parameters
          .RX_STAT_DAT_WIDTH_64(RX_STAT_DAT_WIDTH_64))     // RX Frame Status


U_RX (
          .reset_rxclk(reset_rxclk),
          .xlgmii_rxclk(xlgmii_rxclk),
          .rx_start(rx_start),
          .rx_end(rx_end),
          .rx_d(rx_d),
          .rx_dval(rx_dval),
          .rx_final_size(rx_final_size),
          .frame_err(frame_err),
          .phy_err(phy_err),
          .rs_fault(rs_fault),
          .rx_data_int(rx_data_int),
          .rx_sop_int(rx_sop_int),
          .rx_eop_int(rx_eop_int),
          .rx_wren_int(rx_wren_int),
          .rx_dval_int(rx_dval_int),
          .rx_a_full(rx_a_full),
          .rx_stat_data(rx_stat_data),
          .rx_stat_wren(rx_stat_wren),
          .rx_preamble(rx_preamble),
          .pause_fwd(pause_fwd),
          .rx_enable(rx_enable),
          .mac_addr(mac_addr),
          .frm_lgth_max(frm_lgth_max),
          .sfd_any(sfd_any),
          .pfc_mode(pfc_mode_r),                //  sync'ed
          .frm_align_err(frm_align_err),
          .rsv_stat_val(rsv_stat_val),
          .rsv_stat(rsv_stat),
          .rsv_stat_pfc(rsv_stat_pfc)
        `ifdef MTIPM10_MAGIC_ENA
          ,
          .magic_rxstop(magic_rxstop)
        `endif
           );


cont_40g_txc U_TX (
          .reset_txclk(reset_txclk),
          .xlgmii_txclk(xlgmii_txclk),
          .xlgmii_txclk_ena(xlgmii_txclk_ena),
          .tx_data_int(tx_data_int),
          .tx_sop_int(tx_sop_int),
          .tx_eop_int(tx_eop_int),
          .tx_data_err_int(tx_data_err_int),
          .tx_preamble(tx_preamble),
          .tx_sav_int(tx_sav_int),
          .tx_empty(tx_empty),
          .tx_stat(tx_stat),
          .tx_stat_empty(tx_stat_empty),
          .tx_stat_pgen(tx_stat_pgen),
          .tx_rden_int(tx_rden_int),
          .tx_rden_int_sop(tx_rden_int_sop),
          .tx_underflow(tx_underflow),
          .tx_isidle(tx_isidle),
        `ifdef MTIPMAC_1SIF
          .os_tx_err(os_tx_err),
        `endif
          .tx_val(tx_val),
          .tx_d(tx_d),
          .tx_start(tx_start),
          .tx_end(tx_end),
          .tx_err(tx_err),
          .tx_final_size(tx_final_size),
          .txipg_dval(txipg_dval),
          .txipg_eop(txipg_eop),
          .txipg_mod(txipg_mod),
          .txipg_crc(txipg_crc),
          .txipg_sub1(txipg_sub1),
          .txipg_done(txipg_done),
          .txipg_dic(txipg_dic),
          .txipg_norm(txipg_norm),
          .rs_fault(rs_fault_ored),
          .tx_enable(tx_enable),
          .tx_pad_in(tx_pad_in),
          .tx_flush(tx_flush),
          .pfc_mode(pfc_mode_t),                //  sync'ed
          .lowp_ena_t(lowp_ena_t),
          `ifdef MTIPM64B_SHORT_IPG
          .short_ipg(short_ipg_t),
          `endif 
          .tsv_stat_val(tsv_stat_val),
          .tsv_stat(tsv_stat),
          .tsv_stat_pfc(tsv_stat_pfc),
          .tsv_stat_pgen(tsv_stat_pgen)
          );


endmodule // module top_40g_contc
